 /*
 * UMLSynch - VPSDE plugin part
 * http://umlsynch.googlecode.com
 *
 * Copyright 2008-2010, Evgeny Alexeyev
 * Licensed under the EPL - v1.0
 * http://www.eclipse.org/legal/epl-v10.html
 *
 */

package com.googlecode.umlsynch.vpsde.rpc.VPSDEDiagramManager;

import java.awt.Point;
import java.io.IOException;
import java.util.Iterator;

import com.googlecode.umlsynch.rpc.TClassDescriptor;
import com.googlecode.umlsynch.vpsde.rpc_old.EclipseOperationServer.VPSDEClassDescription;
import com.vp.plugin.ApplicationManager;
import com.vp.plugin.DiagramManager;
import com.vp.plugin.action.VPContext;
import com.vp.plugin.diagram.IClassDiagramUIModel;
import com.vp.plugin.diagram.IDiagramElement;
import com.vp.plugin.diagram.IDiagramUIModel;
import com.vp.plugin.model.IAttribute;
import com.vp.plugin.model.IClass;
import com.vp.plugin.model.IGeneralization;
import com.vp.plugin.model.IModelElement;
import com.vp.plugin.model.IOperation;
import com.vp.plugin.model.IReference;
import com.vp.plugin.model.IRelationship;
import com.vp.plugin.model.factory.IModelElementFactory;

public class VPClassDiagramManager {
	VPClassDiagramConnectorsManager ConnectorsManager = new VPClassDiagramConnectorsManager();

	private static VPClassDiagramManager Singletone = null;

	public static VPClassDiagramManager instance() {
		if (Singletone == null) {
			Singletone = new VPClassDiagramManager();
		}
		return Singletone;
	}

	private IDiagramElement FindClassOnDiagram(IDiagramUIModel dm, String superclass)
	{
		Iterator dmIter = dm.diagramElementIterator();
		
		while (dmIter.hasNext()) {
			IDiagramElement de = (IDiagramElement) dmIter.next();
			IModelElement me = de.getModelElement();
		
			if ((me instanceof IClass) && (me.getName().equals(superclass))) {
				return de;
			}			
		}		
		
		return null;		
	}
	
	public IDiagramElement AddClassToDiagram(IDiagramUIModel diagramModel, String className)
	{	
	  DiagramManager diagramManager = ApplicationManager.instance().getDiagramManager();

	  IDiagramElement diagramElement = FindClassOnDiagram(diagramModel, className);

	  IClass classModelElement = null;
	  IReference ref;

	  diagramModel.setAutoFitShapesSize(true);
	  diagramModel.setAlignToGrid(true);
	  
	  if (diagramElement == null)
      {
		  classModelElement = IModelElementFactory.instance().createClass(); 
		  classModelElement.setName(className);				
		  diagramElement = diagramManager.createDiagramElement(diagramModel, classModelElement);
		  
		  diagramElement.getModelElement().setName(className);
		  
		  
		  
		  // TODO: relocate the diagram element correctly
		  //diagramElement.setX(100);
		  //diagramElement.setY(100);		  
      }

	  return diagramElement;
	}

		
	public IDiagramElement AddConnectedClass(IDiagramUIModel diagramModel, 
								  IDiagramElement de, 
								  String className,
								  String connectorType)
	{
		IClass localClass = null;
		IModelElement me = de.getModelElement();
		ApplicationManager.instance().getViewManager().showMessage("C1 " + className);
		if (me instanceof IClass)
			localClass = (IClass)me;		 
		else 
			return null;
		ApplicationManager.instance().getViewManager().showMessage("C2");
		IDiagramElement newDiagramElement = AddClassToDiagram(diagramModel, className);
		
		if (newDiagramElement == null)
			return null;
		ApplicationManager.instance().getViewManager().showMessage("C3");
		ConnectorsManager.AddConnector(diagramModel, de, newDiagramElement, connectorType);
		ApplicationManager.instance().getViewManager().showMessage("C4");
		return newDiagramElement;
	}

	private boolean isClassOperationAvailable(IClass localClass, String operation)
	{
		Iterator iter = localClass.operationIterator();

		while (iter.hasNext()) {
			IOperation oper = (IOperation)iter.next();
			if (oper.getName().equals(operation)) {
				return true;
			}				
		}		
		return false;		
	}
	
	public void AddClassOperations(VPContext context, IClass selectedElement, TClassDescriptor result) {
		IClass localClass = selectedElement; 

		for (int i=0; i< result.operations.length; i++) {
			ApplicationManager.instance().getViewManager().showMessage("AddAllOperation:" + result.operations[i].name);
			if (!isClassOperationAvailable(localClass, result.operations[i].name)) {
				IOperation op1 = IModelElementFactory.instance().createOperation();
				op1.setName(result.operations[i].name);
				op1.setVisibility(result.operations[i].visibility);	
				localClass.addOperation(op1);				
			}			
		}
	}
	
	public void AddClassMembers(VPContext context, IDiagramElement selectedElement, TClassDescriptor result) {
		IClass localClass = (IClass)selectedElement.getModelElement(); 
		
        // Add operation if it is not available, yet 
		for (int i=0; i< result.members.length; i++) {
			ApplicationManager.instance().getViewManager().showMessage("AddAllMebers 1" + result.members[i].name);
			if (!isClassOperationAvailable(localClass, result.members[i].name)) {
				IAttribute attrib1 = IModelElementFactory.instance().createAttribute();
				attrib1.setName(result.members[i].name);
				attrib1.setVisibility(result.members[i].visibility);
				localClass.addAttribute(attrib1);				
			}
		}
	}
	
	public String GetClasPropery(IModelElement diagramElement, String propName) {
		return VPPropertyManager.instance().GetProperty(diagramElement, propName);
	}

	public void SetClasPropery(IModelElement diagramElement, String propName, String propValue) {
		VPPropertyManager.instance().SetProperty(diagramElement, propName, propValue);

		if (propName.equals(this.PROP_CLASS_FILE_NAME)) {
			IReference ref = IModelElementFactory.instance().createReference();
			String projName = ApplicationManager.instance().getProjectManager().getProject().getName();
			String projPath = ApplicationManager.instance().getProjectManager().getProject().getProjectFile().getPath();
			String absPath = ApplicationManager.instance().getProjectManager().getProject().getProjectFile().getAbsolutePath();
			String canPath = null;
			try {
				canPath = ApplicationManager.instance().getProjectManager().getProject().getProjectFile().getCanonicalPath();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			ApplicationManager.instance().getViewManager()
			.showMessage("Path: " + projPath + "\n" + absPath + "\n" + canPath);	
			ref.setUrl("d:/workspace/" + projName + "/" + propValue );
			if (diagramElement instanceof IClass) {
				IClass refClass = (IClass)diagramElement;
				refClass.addReference(ref);
			}
		}
	}
	
	public static String PROP_CLASS_FILE_NAME = "CLASS_FILE_NAME";
	public static String PROP_CLASS_PROJECT_NAME = "CLASS_PROJECT_NAME";
	public static String PROP_CLASS_LANGUAGE = "CLASS_LANGUAGE";	
	public static String PROP_CLASS_NAME = "CLASS_FILE_NAME";
	public static String PROP_CLASS_ILE_NAME = "CLASS_FILE_NAME";
	
	
}
